"""
https://blog.csdn.net/qq_46092061/article/details/117657754
"""
# 绘制素描图 sketch：草图，素描，梗概
from PIL import Image
import numpy as np


# 绘制素描图
def makeSketch(from_path, save_path):
    # 获取图片，将图片转化为，mode=L:灰度图，每个像素用 8 位二进制代码表示，astype：并将像素点转化为浮点类型的二维矩阵
    a = np.array(Image.open(from_path).convert('L')).astype('float')
    depth = 10.  # (0-100)
    '''
    梯度计算采用二阶精确中心差分  
    在内点和一阶或二阶精确的一面  
    (向前或向后)边界上的差异。  
    因此，返回的梯度具有与输入数组相同的形状。  
    '''
    grad = np.gradient(a)  # 获取图像灰度的梯度值 返回元组 gradient:梯度
    grad_x, grad_y = grad  # 分别取横纵图像梯度值

    grad_x = grad_x * depth / 100.
    grad_y = grad_y * depth / 100.

    A = np.sqrt(grad_x ** 2 + grad_y ** 2 + 1.)
    uni_x = grad_x / A
    uni_y = grad_y / A
    uni_z = 1. / A
    vec_el = np.pi / 2.2  # 光源的俯视角度，弧度值
    vec_az = np.pi / 4.  # 光源的方位角度，弧度值
    dx = np.cos(vec_el) * np.cos(vec_az)  # 光源对 x轴的影响
    dy = np.cos(vec_el) * np.sin(vec_az)  # 光源对 y轴的影响
    dz = np.sin(vec_el)  # 光源对z 轴的影响

    b = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 光源归一化
    b = b.clip(0, 255)

    im = Image.fromarray(b.astype('uint8'))  # 重构图像  a = np.asarray(im)
    im.save(save_path)
    print('绘制素描画成功')


if __name__ == '__main__':
    pre = 'C:\\Users\\jiaohongtao\\Desktop\\imgs'
    getUrl = pre + r'/ceshi6.jpg'
    saveUrl = pre + r'/ceshi6_sumiao.jpg'
    makeSketch(getUrl, saveUrl)
